import {
	_decorator,
	Component,
	Node,
	Enum,
	Vec3,
	EventTouch,
	UITransformComponent,
	view,
	v3,
} from "cc";
const { ccclass, property } = _decorator;

//触摸类型
export enum TOUCH_TYPE {
	DEFAULT = 0, //按钮和背景距离不变，背景位置与触碰点一致，不可改变按钮背景位置，按钮背景随着按钮移动而移动，松手后无法恢复到初始位置
	FOLLOW, //按钮和背景距离不变，背景位置与触碰点一致，不可改变按钮背景位置，按钮背景随着按钮移动而移动，松手后恢复到初始位置
	FOLLOW_ALWAYS, //按钮和背景距离不变，背景位置与触碰点一致，可改变按钮背景位置，按钮背景随着按钮移动而移动，松手后恢复到初始位置
	FOLLOW_DOT, //按钮和背景距离可改变，按钮位置与触碰点可不一致，不可改变按钮背景位置，按钮背景不随着按钮移动而移动，松手后恢复到初始位置
}

//方向
export enum DIRECTION_TYPE {
	FOUR = 4,
	EIGHT = 8,
	ALL = 0,
}

export enum EventJoystick{
    start,
    move,
    end,
}

const screenHeight = view.getVisibleSize().height; //屏幕可视范围高度
const screenWidth = view.getVisibleSize().width;

Enum(TOUCH_TYPE);
Enum(DIRECTION_TYPE);

@ccclass("Joystick")
export class Joystick extends Component {
	@property({ type: Node, displayName: "摇杆背景节点" })
	public nodeRing: Node = null!;

	@property({ type: Node, displayName: "摇杆节点" })
	public nodeDot: Node = null!;

	@property({ type: TOUCH_TYPE, displayName: "触摸类型" })
	public touchType: TOUCH_TYPE = TOUCH_TYPE.DEFAULT;

	@property({ type: DIRECTION_TYPE, displayName: "方向类型" })
	public directionType = DIRECTION_TYPE.ALL;

	@property({ displayName: "启动半透明"})
	public isEnableTransparent: boolean = false;

	@property({ displayName: "点击跟随" })
	public isFollowStart: boolean = false;

	@property({ displayName: "内圈大小" })
	public innerSize: number = 10;

	onLoad() {

	}

    start(){

    }

    public setAlpha(){

    }
    
	update(deltaTime: number) {
		//设置终终点按钮位置
		if (this._targetRingPos) {
			this._curRingPos_1.set(0, 0, 0);
			Vec3.lerp(
				this._curRingPos_1,
				this.nodeRing.position,
				this._targetRingPos,
				20 * deltaTime
			);
			this.nodeRing.setPosition(this._curRingPos_1);
		}

        //根据频率操作
		this._currentTime += deltaTime;
		if (this._currentTime >= this._checkInterval) {
			this._currentTime = 0;
			if (this.isMoving) {
				if (this.angle !== this._oldAngle) {
					this._oldAngle = this.angle;
					//GameManager.scriptPlayer.playAction({action: constant.PLAYER_ACTION.MOVE, value: this.angle});
				}
			} else {
				this.isMoving = false;
				// if (GameManager.scriptPlayer.isMoving) {
				//     GameManager.scriptPlayer.playAction({action: constant.PLAYER_ACTION.STOP_MOVE});
				// }
			}
		}
	}

	onEnable() {
		this.node.on(Node.EventType.TOUCH_START, this._touchStartEvent, this);
		this.node.on(Node.EventType.TOUCH_MOVE, this._touchMoveEvent, this);

		this.node.on(Node.EventType.TOUCH_END, this._touchEndEvent, this);
		this.node.on(Node.EventType.TOUCH_CANCEL, this._touchEndEvent, this);
	}

	onDisable() {
		this.node.off(Node.EventType.TOUCH_START, this._touchStartEvent, this);
		this.node.off(Node.EventType.TOUCH_MOVE, this._touchMoveEvent, this);

		this.node.off(Node.EventType.TOUCH_END, this._touchEndEvent, this);
		this.node.off(Node.EventType.TOUCH_CANCEL, this._touchEndEvent, this);
	}

	// update (deltaTime: number) {
	//     // [4]
	// }

	private _touchStartEvent(event: EventTouch) {
		// this.dot.opacity = 255;
		this._targetRingPos = null!;
		let touch = event.getUILocation();
		this._touchStartLocation.set(touch.x, touch.y, 0);
		let touchPos = this.node
			.getComponent(UITransformComponent)
			?.convertToNodeSpaceAR(this._touchStartLocation) as Vec3;
		if (!this._oriRingPos) {
			this._oriRingPos = this.nodeRing.getPosition().clone();
		}
		// 记录摇杆位置，给touch move使用
		this._stickPos.set(touchPos);

		this._isOutInnerSize = false;

		if (!this.isFollowStart) {
			touchPos = this.nodeRing
				.getComponent(UITransformComponent)
				?.convertToNodeSpaceAR(this._touchStartLocation) as Vec3;

			//触摸点与圆圈中心的距离
			let distance = touchPos.length();
			let width = this.nodeRing.getComponent(UITransformComponent)
				?.contentSize.width as number;
			//圆圈半径
			let radius = width / 2;

			//手指在圆圈内触摸,控杆跟随触摸点
			if (radius > distance) {
				this.nodeDot.setPosition(touchPos);
				this._updateAngle(touchPos);
				return true;
			}
			return false;
		} else {
			//设置遥感可移动范围
			if (this.touchType == TOUCH_TYPE.FOLLOW) {
				touchPos.y =
					touchPos.y >= -screenHeight / 6
						? -screenHeight / 6
						: touchPos.y;
                touchPos.x =
                touchPos.x >= -screenWidth / 6
                    ? -screenWidth / 6
                    : touchPos.x;
			}
			this.nodeRing.setPosition(touchPos);
		}
	}

	private _touchMoveEvent(event: EventTouch) {
		let touch = event.getUILocation();
		this._touchMoveLocation.set(touch.x, touch.y, 0);
		let touchPos = this.nodeRing
			.getComponent(UITransformComponent)
			?.convertToNodeSpaceAR(this._touchMoveLocation) as Vec3;

		if (this.touchType === TOUCH_TYPE.FOLLOW) {
			let offsetPos = v3(
				touchPos.x - this._stickPos.x,
				touchPos.y - this._stickPos.y,
				0
			);
			touchPos = offsetPos;
		}

		let distance = touchPos.length();

		if (distance > this.innerSize) {
			this.isMoving = true;
			this._isOutInnerSize = true;
		} else {
			this._isOutInnerSize = false;
		}

		//有拖动且有角度才视为开始游戏
		this._currentTime = this._checkInterval;

		let width = this.nodeRing.getComponent(UITransformComponent)?.contentSize
			.width as number;
		//圆圈半径
		let radius = width / 2;
		let rate = 0;
		// 由于摇杆的position是以父节点为锚点，所以定位要加上ring和dot当前的位置(stickX,stickY)
		if (radius > distance) {
			rate = Number((distance / radius).toFixed(3));
			this.nodeDot.setPosition(touchPos);
		} else if (this.touchType !== TOUCH_TYPE.FOLLOW_DOT) {
			rate = 1;
			//控杆永远保持在圈内，并在圈内跟随触摸更新角度
			let radian = Math.atan2(touchPos.y, touchPos.x);

			let x = Math.cos(radian) * radius;
			let y = Math.sin(radian) * radius;
			this._movePos.set(x, y, 0);
			if (this.touchType === TOUCH_TYPE.FOLLOW_ALWAYS) {
				this._curRingPos_2.set(touch.x - x, touch.y - y, 0);
				let ringPos = this.node
					.getComponent(UITransformComponent)
					?.convertToNodeSpaceAR(this._curRingPos_2) as Vec3;
				this._targetRingPos = ringPos;
			}

			this.nodeDot.setPosition(this._movePos);
		} else {
			// 点跟随移动
			this.nodeDot.setPosition(touchPos);
		}
		//更新角度
		this._updateAngle(touchPos);
		//更新遥感移动距离百分比
		this._distanceRate = rate;
	}

	private _touchEndEvent(event: EventTouch) {
		if (!this.isMoving) {
		} else {
			let touch = event.getUILocation();
			this._touchEndLocation.set(touch.x, touch.y, 0);
			let touchPos = this.nodeRing
				.getComponent(UITransformComponent)
				?.convertToNodeSpaceAR(this._touchEndLocation) as Vec3;
			let isDragToInner = false;
			if (touchPos.length() < this.innerSize) {
				//取消掉
				isDragToInner = true;
			}
            this.node.emit('');
		}

		this.isMoving = false;
		this.nodeDot.setPosition(this._oriDotPos);

		if (
			this.touchType === TOUCH_TYPE.FOLLOW ||
			this.touchType === TOUCH_TYPE.FOLLOW_ALWAYS ||
			this.touchType === TOUCH_TYPE.FOLLOW_DOT
		) {
			this._targetRingPos = null!;
			this.nodeRing.setPosition(this._oriRingPos);
		}
	}

	public reset() {
		this.isMoving = false;
		this.nodeDot.setPosition(this._oriDotPos);
	}

	public get distanceRate() {
		return this._distanceRate;
	}

	public get angle() {
		return this._angle;
	}
	public set angle(v: number) {
		this._angle = v;
	}

	private _updateAngle(pos: Vec3) {
		this._angle = Math.atan2(pos.y, pos.x) * 180 / Math.PI |0;
		return this._angle;
	}
	public isMoving: boolean = false; //是否正在移动

	private _angle: number = 0; //当前的角度
	private _stickPos: Vec3 = new Vec3(); //遥感位置
	private _oriRingPos: Vec3 = null!; //圆圈初始位置
	private _targetRingPos: Vec3 = new Vec3(); //圆圈背景位置
	private _touchStartLocation: Vec3 = new Vec3(); //开始触碰位置
	private _touchMoveLocation: Vec3 = new Vec3(); //移动触碰位置
	private _touchEndLocation: Vec3 = new Vec3(); //结束触碰位置
	private _isOutInnerSize: Boolean = false; //终点拖动的点是否超出按钮圆圈背景
	private _distanceRate: number = 0; //遥感移动距离比
	private _checkInterval: number = 0.04; //刷新频率
	private _oldAngle: number = 0; //之前的角度
	private _currentTime: number = 0; //当前累积时间
	private _oriDotPos: Vec3 = new Vec3(); //中间按钮初始坐标
	private _movePos: Vec3 = new Vec3(); //移动坐标
	private _curRingPos_1: Vec3 = new Vec3(); //当前圆圈坐标
	private _curRingPos_2: Vec3 = new Vec3(); //
}
